#pragma once
#include "base/core/singleton.h"
#include "Common/ServerDefine.h"
#include "ProtoBuffer/AllProtocol.h"
//#include "AllProtocol.h"
#include "Common/Utility/Service.h"
#include "Common/CharacterDefine.h"
#include "Common/Utility/JsonUtility.h"


struct gateClient
{
	uint32_t gateId;
	uint32_t clientId;
	gateClient()
	{
		gateId = 0;
		clientId = 0;
	}
};

class LogicService : public Service, public ManualSingleton<LogicService>
{
	friend class ManualSingleton<LogicService>;
	typedef std::unordered_map<uint32_t, ServiceConnect>  CONNECT_MAP;

protected:
	uint32_t            m_zid;
	char                m_listenIP[ADDRESS_IP_LENGTH];
	char                m_outerIP[ADDRESS_IP_LENGTH];
	uint16_t            m_outerPort;
	uint64_t            m_startMark;

	uint32_t            m_connectFlag;
	uint64_t            m_lastDayChangeTime;
	uint64_t            m_syncStateTick;
	uint64_t            m_dbRequestCount;

	IMessageDispatch    *m_pMessageDispatch;

	ServiceConnect      m_logServer;
	ServiceConnect      m_dbproxyServer;
	ServiceConnect      m_gateServer;
	ServiceConnect      m_centerServer;

	CONNECT_MAP			m_gateConnectMap;;

	bool                m_loadAllMapIds;

	uint64_t            m_openTime;//游戏开服时间
	uint32_t		    m_weekCountFromOpen;//当前的周数（从开服时间算起）

public:
	virtual bool Init(Net* net, const char* configFile)override;
	virtual void UnInit()override;
	virtual bool Update(uint64_t tick)override;
	virtual bool Quit() override;
	virtual bool HandleConsoleCmd(const char* cmd)override;
	virtual IMessageDispatch *GetServiceMessageDispatch() override;

	bool SendDataToDBProxy(const char* buf, uint32_t length);
	bool SendDataToDBProxy(uint16_t module,uint16_t protocolCmd, ProtoBufBase* buf);
	bool SendCmdToDBProxy(uint32_t protocolCmd);
	bool IsConnectDBProxy();

	bool SendDataToCenter(uint16_t module,uint16_t protocolCmd, ProtoBufBase* buf);
	bool IsConnectCenter();

	bool SendDataToClient(CharIDType cid, uint16_t module, uint16_t command, ProtoBufBase* data);
	bool SendDataToClient(SET_UINT64& setCharID, uint16_t module, uint16_t command, ProtoBufBase* buf);
	bool SendDataToAllClient(uint16_t moudle, uint16_t command, ProtoBufBase* buf);
	bool SendDataToClient(MAP_UINT32_LST_UINT32& gateClientsMap, uint16_t module, uint16_t command, ProtoBufBase* buf);
	bool SendDataToClient(uint32_t gateId, LIST_UINT32 & clientIds, uint16_t module, uint16_t command, ProtoBufBase* buf);
	bool SendDataToClient(uint32_t gateId, uint32_t clientId, uint16_t module, uint16_t command, ProtoBufBase* buf);

	bool SendLogToLogServer(JsonObject& json);

	bool ResetSessionTimeout(ISession* session, uint32_t timeMsec = 0xFFFFFFFF);
	Net*        GetNetInstance() { return m_net; }
	uint64_t    GetDBRequestCount();

	const char* GetOuterIP() { return m_outerIP; }
	uint16_t    GetOuterPort() { return m_outerPort; }
	uint64_t	GetStartMark() { return m_startMark; }
	uint32_t    GetZID()   { return m_zid; }
	uint64_t    GetGameOpenTime(){ return m_openTime; }
	uint32_t	GetWeekCountFromOpen(){ return m_weekCountFromOpen; };//获取从开服到当前的周数
	void		WeekUpdate(uint64_t unixSec);
	void		DailyUpdate(uint64_t unixSec);
	void		WeekZeroUpdate(uint64_t unixSec);
	void		DailyZeroUpdate(uint64_t unixSec);
protected:
	bool _LoadConfig(const char* config_file);
	bool _ProcessConnection();
	void _SetConnectFlag(ServiceConnectFlag flag, bool open);
	bool _SyncServiceState();
	bool _SyncServerLoad(bool force);
	bool _CheckDayChange();
	void _OnDayChange();
	bool _CheckLuaStackLeak();
	void _CalcWeekCountFromOpen(uint64_t curTime);

	ServiceConnect* GetGateConnect(uint32_t gateId);

	static bool _OnCloseServer(ISession* session, void* context, CloseFlag flag);

	static bool _OnConnectDBProxy(ISession* session, void* context, bool success);
	static bool _OnConnectLogServer(ISession* session, void* context, bool success);
	static bool _OnConnectCenterServer(ISession* session, void* context, bool success);
	static bool _OnConnectGateServer(ISession* session, void* context, bool success);

	bool _Register2Center();
	bool _Register2Gate(ISession *pSession);
	bool _Register2Zone(ISession *pSession);

protected:
	LogicService();
	virtual ~LogicService()override;
};

#define g_MakeLogicService() (LogicService::Instance())
#define g_GetLogicService()  (LogicService::GetInstance())
#define g_DelLogicService()  (LogicService::Destroy())
